{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Early stopping"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Installing packages:\n",
      "\t.package(path: \"/home/jupyter/notebooks/swift/FastaiNotebook_05_anneal\")\n",
      "\t\tFastaiNotebook_05_anneal\n",
      "With SwiftPM flags: []\n",
      "Working in: /tmp/tmp8ww6oc24/swift-install\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "warning: /home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "/home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)[1/9] Compiling FastaiNotebook_05_anneal 01_matmul.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[2/9] Compiling FastaiNotebook_05_anneal 03_minibatch_training.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[3/9] Compiling FastaiNotebook_05_anneal 02_fully_connected.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[4/9] Compiling FastaiNotebook_05_anneal 02a_why_sqrt5.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[5/9] Compiling FastaiNotebook_05_anneal 00_load_data.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[6/9] Compiling FastaiNotebook_05_anneal 05_anneal.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[7/9] Compiling FastaiNotebook_05_anneal 04_callbacks.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[8/9] Compiling FastaiNotebook_05_anneal 01a_fastai_layers.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[9/10] Merging module FastaiNotebook_05_anneal\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "/home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)[10/11] Compiling jupyterInstalledPackages jupyterInstalledPackages.swift\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "[11/12] Merging module jupyterInstalledPackages\n",
      "/home/jupyter/swift/usr/bin/swift: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift)\n",
      "/home/jupyter/swift/usr/bin/swiftc: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swiftc)\n",
      "/home/jupyter/swift/usr/bin/swift-autolink-extract: /home/jupyter/anaconda3/lib/libuuid.so.1: no version information available (required by /home/jupyter/swift/usr/bin/swift-autolink-extract)\n",
      "[12/12] Linking libjupyterInstalledPackages.so\n",
      "Initializing Swift...\n",
      "Installation complete!\n"
     ]
    }
   ],
   "source": [
    "%install-location $cwd/swift-install\n",
    "%install '.package(path: \"$cwd/FastaiNotebook_05_anneal\")' FastaiNotebook_05_anneal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//export\n",
    "import Path\n",
    "import TensorFlow\n",
    "import Python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import FastaiNotebook_05_anneal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('inline', 'module://ipykernel.pylab.backend_inline')\n"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%include \"EnableIPythonDisplay.swift\"\n",
    "IPythonDisplay.shell.enable_matplotlib(\"inline\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "let data = mnistDataBunch(flat: true)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "let (n,m) = (60000,784)\n",
    "let c = 10\n",
    "let nHid = 50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "func optFunc(_ model: BasicModel) -> SGD<BasicModel> {return SGD(for: model, learningRate: 1e-2)}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "func modelInit() -> BasicModel {return BasicModel(nIn: m, nHid: nHid, nOut: c)}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "let learner = Learner(data: data, lossFunc: softmaxCrossEntropy, optFunc: optFunc, modelInit: modelInit)\n",
    "let recorder = learner.makeRecorder()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check the previous callbacks load."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learner.delegates = [learner.makeTrainEvalDelegate(), learner.makeShowProgress(),\n",
    "                     learner.makeNormalize(mean: mnistStats.mean, std: mnistStats.std),\n",
    "                     learner.makeAvgMetric(metrics: [accuracy]), recorder]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0: [0.30931613, 0.912]                                                   \n",
      "Epoch 1: [0.2514467, 0.9287]                                                   \n",
      "                                                                           \r"
     ]
    }
   ],
   "source": [
    "learner.fit(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Make an extension to quickly load them. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "// export\n",
    "//TODO: when recorder can be accessed as a property, remove it from the return\n",
    "extension Learner where Opt.Scalar: PythonConvertible {\n",
    "    public func makeDefaultDelegates(metrics: [(Output, Label) -> TF] = []) -> Recorder {\n",
    "        let recorder = makeRecorder()\n",
    "        delegates = [makeTrainEvalDelegate(), makeShowProgress(), recorder]\n",
    "        if !metrics.isEmpty { delegates.append(makeAvgMetric(metrics: metrics)) }\n",
    "        return recorder\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Control Flow test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "extension Learner {\n",
    "    public class TestControlFlow: Delegate {\n",
    "        public override var order: Int { return 3 }\n",
    "        \n",
    "        var skipAfter,stopAfter: Int\n",
    "        public init(skipAfter:Int, stopAfter: Int){  (self.skipAfter,self.stopAfter) = (skipAfter,stopAfter) }\n",
    "        \n",
    "        public override func batchWillStart(learner: Learner) throws {\n",
    "            print(\"batchWillStart\")\n",
    "            if learner.currentIter >= stopAfter {\n",
    "                throw LearnerAction.stop(reason: \"*** stopped: \\(learner.currentIter)\")\n",
    "            }\n",
    "            if learner.currentIter >= skipAfter {\n",
    "                throw LearnerAction.skipBatch(reason: \"*** skipBatch: \\(learner.currentIter)\")\n",
    "            }\n",
    "        }\n",
    "        \n",
    "        public override func trainingDidFinish(learner: Learner) {\n",
    "            print(\"trainingDidFinish\")\n",
    "        }\n",
    "        \n",
    "        public override func batchSkipped(learner: Learner, reason: String) {\n",
    "            print(reason)\n",
    "        }\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "let learner = Learner(data: data, lossFunc: softmaxCrossEntropy, optFunc: optFunc, modelInit: modelInit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learner.delegates = [type(of: learner).TestControlFlow(skipAfter:5, stopAfter: 8),\n",
    "                     learner.makeTrainEvalDelegate()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "batchWillStart\r\n",
      "batchWillStart\r\n",
      "batchWillStart\r\n",
      "batchWillStart\r\n",
      "batchWillStart\r\n",
      "batchWillStart\r\n",
      "*** skipBatch: 5\r\n",
      "batchWillStart\r\n",
      "*** skipBatch: 6\r\n",
      "batchWillStart\r\n",
      "*** skipBatch: 7\r\n",
      "batchWillStart\r\n",
      "trainingDidFinish\r\n"
     ]
    }
   ],
   "source": [
    "learner.fit(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check if the orders were taken into account:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "▿ 2 elements\n",
       "  - .0 : 0\n",
       "  - .1 : 3\n"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(learner.delegates[0].order,learner.delegates[1].order)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### LR Finder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "// export\n",
    "extension Learner where Opt.Scalar: BinaryFloatingPoint {\n",
    "    public class LRFinder: Delegate {\n",
    "        public typealias ScheduleFunc = (Float) -> Float\n",
    "\n",
    "        // A learning rate schedule from step to float.\n",
    "        private var scheduler: ScheduleFunc\n",
    "        private var numIter: Int\n",
    "        private var minLoss: Float? = nil\n",
    "        \n",
    "        public init(start: Float = 1e-5, end: Float = 10, numIter: Int = 100) {\n",
    "            scheduler = makeAnnealer(start: start, end: end, schedule: expSchedule)\n",
    "            self.numIter = numIter\n",
    "        }\n",
    "        \n",
    "        override public func batchWillStart(learner: Learner) {\n",
    "            learner.opt.learningRate = Opt.Scalar(scheduler(Float(learner.currentIter)/Float(numIter)))\n",
    "        }\n",
    "        \n",
    "        override public func batchDidFinish(learner: Learner) throws {\n",
    "            if minLoss == nil {minLoss = learner.currentLoss.scalar}\n",
    "            else { \n",
    "                if learner.currentLoss.scalarized() < minLoss! { minLoss = learner.currentLoss.scalarized()}\n",
    "                if learner.currentLoss.scalarized() > 4 * minLoss! { \n",
    "                    throw LearnerAction.stop(reason: \"Loss diverged\")\n",
    "                }\n",
    "                if learner.currentIter >= numIter { \n",
    "                    throw LearnerAction.stop(reason: \"Finished the range.\") \n",
    "                }\n",
    "            }\n",
    "        }\n",
    "        \n",
    "        override public func validationWillStart(learner: Learner<Label, Opt>) throws {\n",
    "            //Skip validation during the LR range test\n",
    "            throw LearnerAction.skipEpoch(reason: \"No validation in the LR Finder.\")\n",
    "        }\n",
    "    }\n",
    "    \n",
    "    public func makeLRFinder(start: Float = 1e-5, end: Float = 10, numIter: Int = 100) -> LRFinder {\n",
    "        return LRFinder(start: start, end: end, numIter: numIter)\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "let learner = Learner(data: data, lossFunc: softmaxCrossEntropy, optFunc: optFunc, modelInit: modelInit)\n",
    "let recorder = learner.makeDefaultDelegates()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learner.delegates.append(learner.makeNormalize(mean: mnistStats.mean, std: mnistStats.std))\n",
    "learner.delegates.append(learner.makeLRFinder())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                                                                             \r"
     ]
    }
   ],
   "source": [
    "learner.fit(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "recorder.plotLRFinder()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "// export\n",
    "//TODO: when Recorder is a property of Learner don't return it.\n",
    "extension Learner where Opt.Scalar: PythonConvertible & BinaryFloatingPoint {\n",
    "    public func lrFind(start: Float = 1e-5, end: Float = 10, numIter: Int = 100) -> Recorder {\n",
    "        let epochCount = data.train.count/numIter + 1\n",
    "        let recorder = makeDefaultDelegates()\n",
    "        delegates.append(makeLRFinder(start: start, end: end, numIter: numIter))\n",
    "        try! self.fit(epochCount)\n",
    "        return recorder\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                                                                             \r"
     ]
    }
   ],
   "source": [
    "let recorder = learner.lrFind()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "recorder.plotLRFinder()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Export"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "success\r\n"
     ]
    }
   ],
   "source": [
    "import NotebookExport\n",
    "let exporter = NotebookExport(Path.cwd/\"05b_early_stopping.ipynb\")\n",
    "print(exporter.export(usingPrefix: \"FastaiNotebook_\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Swift",
   "language": "swift",
   "name": "swift"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
